Skip to content

Fix file dialog crash and drive list on Linux - #279

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/filesystem-browser-linux
Jul 30, 2026
Merged

Fix file dialog crash and drive list on Linux#279
matt-edmondson merged 1 commit into
mainfrom
fix/filesystem-browser-linux

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #273.

The crash

Every file dialog threw as soon as the listed directory held two entries of the same kind:

System.InvalidOperationException: Failed to compare two elements in the array.
 ---> System.ArgumentException: Object must be of type String.
   at System.String.CompareTo(Object value)
   at ktsu.Semantics.Strings.SemanticString`1.CompareTo(Object value)

DrawFileTable sorted with .ThenBy(p => p) over a Collection<IAbsolutePath>. That interface carries no IComparable<T>, so LINQ falls back to Comparer<T>.DefaultObjectComparer → the non-generic IComparable.CompareTo(object) on the underlying semantic string — an overload that accepts only a System.String, not another semantic string.

Sorting now uses the entry's string value, which also gives case-insensitive display order with a deterministic tiebreak for names differing only by case.

I reproduced this outside the UI with an identical stack: despite the issue title it is not Linux-specific, it fires on any platform. The reporter simply hit it first.

The same bug is fixed at the root in ktsu-dev/Semantics#140, but this change stands on its own — sorting by the string value avoids boxing every comparison regardless, and IAbsolutePath still won't have a generic comparer after that lands.

The drives combo

Three separate defects, two Linux-only:

  • The preview label was hardcoded to Drives[0] — on Windows with C:/D:, browsing D:\ still displayed C:\. Now shows the current root.
  • The highlight never matched on Linux. The "current drive" was built from Path.VolumeSeparatorChar, which is '/' on Unix rather than ':', so /home/matt produced garbage like matt//. Now compares against Path.GetPathRoot.
  • The list was unusable on Linux. Environment.GetLogicalDrives() returns every mount point on Unix — 28 entries on my machine, mostly /proc/sys/fs/binfmt_misc, /sys/kernel/debug, /dev/mqueue, /run/user/1000/gvfs, with duplicates. Filtered, deduplicated and sorted, that becomes 4 real entries with the current root highlighted. /run/media is explicitly exempt from the /run exclusion, since that is where Arch and Fedora mount removable media — a blanket filter would have hidden USB drives.

Tests

New tests/ImGui.Popups.Tests project (13 tests) covering the sort and the drive logic. Reverting the sort fix fails 4 of them. Full suite: 603 passed, 1 skipped (a Windows-only drive assertion), builds clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WFRwYRHhEmVMGvrH2BbtbW

Fixes #273. Opening any of the file dialogs threw as soon as the listed directory
held two entries of the same kind:

  System.InvalidOperationException: Failed to compare two elements in the array.
   ---> System.ArgumentException: Object must be of type String.

DrawFileTable sorted with .ThenBy(p => p) over a Collection<IAbsolutePath>. That
interface carries no IComparable<T>, so LINQ falls back to Comparer<T>.Default,
which calls the non-generic IComparable.CompareTo(object) on the underlying semantic
string — and that overload only accepts a System.String, not another semantic string.
Sorting now uses the entry's string value, which also gives case-insensitive display
order with a deterministic tiebreak. Reproduced with an identical stack outside the
UI; despite the issue title it is not Linux-specific.

DrawDrivesCombo was broken in three ways, two of them Linux-only:

- The preview label was hardcoded to Drives[0], so browsing D:\ on Windows still
  displayed C:\. It now shows the current root.
- The "current drive" was built from Path.VolumeSeparatorChar, which is '/' on Unix
  rather than ':', so /home/matt produced garbage like matt// and no entry ever
  highlighted. It now compares against Path.GetPathRoot.
- Environment.GetLogicalDrives() returns every mount point on Unix — 28 entries on
  the development machine, mostly /proc, /sys, /dev and /run pseudo filesystems, with
  duplicates. The list is now filtered, deduplicated and sorted, down to 4 real
  entries. /run/media is exempt from the /run exclusion because that is where Arch and
  Fedora mount removable media.

Adds tests/ImGui.Popups.Tests covering the sort and the drive logic. Reverting the
sort fix fails 4 of them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WFRwYRHhEmVMGvrH2BbtbW
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@matt-edmondson
matt-edmondson merged commit be521d1 into main Jul 30, 2026
5 of 7 checks passed
@matt-edmondson
matt-edmondson deleted the fix/filesystem-browser-linux branch July 30, 2026 07:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] File-related dialogs fail on Linux.

1 participant